base.ImportV1
也太難用了吧...
要記得start
、build
跟finish
的順序,又要記得所產生的Entities
只能在build
跟finish
間取得。
有沒有辦法改寫一下code,給二次開發的兄弟們,一個比較好的使用體驗呢?
是滴!諸位的心聲我們都聽到了,下面就不藏私地跟大家分享我們的解法。
class-based
的Context Manager
,取名為MyImportV1
的class
。_attrs
的class variable
,其型態為tuple
,裡面儲存的三個element,是我們之後想取得的Entity
。__init__
中建立一個self.a
,是一個base.ImportV1
的instance
。__enter__
中,呼叫self.a.start
,並return self.a
。這一步可謂是關鍵,這邊return
的object
,會被當作with ooo as xxx
中的xxx
,也就是我們在Context Manager
中,真正會使用的 object
。大部分的Context Manager
會在這邊return self
,但我們想於Context Manager
中借助base.ImportV1
,所以必須return self.a
。__enter__
,先呼叫self.a.build
,並於最後呼叫self.a.finish
。在build
及finish
之間,就是我們可以動手腳的地方,因為我們只能在此取得產生的Entity
。我們針對self._attrs
打一個迴圈,透過getattr(self.a, _attr)
得到所產生的Entity
,再透過setattr(self, _attr, attr)
,將這些Entity
各自存為一個instance variable
。如此一來,於主程式中我們就能透過MyImportV1
的instance
來取得這些Entity
了。# ctxmgr.py
from ansa import base
class MyImportV1:
_attrs = ('nodes', 'shells', 'solids')
def __init__(self):
self.a = base.ImportV1()
def __enter__(self):
self.a.start()
return self.a
def __exit__(self, exc_type, exc_value, exc_tb):
self.a.build()
for _attr in self._attrs:
attr = getattr(self.a, _attr)
setattr(self, _attr, attr)
self.a.finish()
經過一番乾坤大挪移後:
start
、build
跟finish
了。plate_import_v1
及box_import_v1
可以於Context Manager
的範圍外,取得node
、shells
及solids
了。# box_drop.py
def main():
deck = constants.LSDYNA
set_deck_to(deck)
# plate
plate_prop = create_sec()
plate_mat_prop_id = plate_prop._id
plate_set = create_set(plate_prop, 'plate', deck=deck)
l_p, w_p, en1_p, en2_p = 100, 100, 10, 10
z_elv_p, move_xy_p, rot_angle_p = 0, None, None
plate_import_v1 = MyImportV1()
with plate_import_v1 as import_v1:
create_plate_v1(import_v1,
l_p,
w_p,
en1_p,
en2_p,
plate_mat_prop_id,
z_elv=z_elv_p,
move_xy=move_xy_p,
rot_angle=rot_angle_p,
deck=deck)
plate_nodes = plate_import_v1.nodes
plate_shells = plate_import_v1.shells
# box
box_prop = create_sec(sec_type=SecType.SECTION_SOLID)
box_mat_prop_id = box_prop._id
box_set = create_set(box_prop, 'box', deck=deck)
l_b, w_b, h_b, en1_b, en2_b, en3_b = 50, 50, 50, 10, 10, 10
z_elv_b, move_xy_b, rot_angle_b = 5, (50, 20), 45
box_import_v1 = MyImportV1()
with box_import_v1 as import_v1:
create_box_v1(import_v1,
l_b,
w_b,
h_b,
en1_b,
en2_b,
en3_b,
box_mat_prop_id,
z_elv=z_elv_b,
move_xy=move_xy_b,
rot_angle=rot_angle_b,
deck=deck)
box_nodes = box_import_v1.nodes
box_solids = box_import_v1.solids
[Day18]我們準備暫時抽離這不斷精進,不斷改code的十天,來寫點tests吧!